unit StockDealAgentApp;

interface

uses           
  Sysutils, Windows,   
  UtilsHttp,
  BaseApp,          
  define_price,
  define_dealItem,
  define_stockapp,
  define_StockDataApp,
  define_zsprocess,
  win.process;

type
  PDealAgentAppData = ^TDealAgentAppData;
  TDealAgentAppData = record                   
    ZsProcess       : TZsProcess;
    ZsMainWnd       : TZsWndMain;
  end;
               
  TDealAgentApp = class(BaseApp.TBaseAppAgent)
  protected         
    fDealAgentAppData: TDealAgentAppData;
  public               
    constructor Create(AHostApp: TBaseApp); override;
    destructor Destroy; override;    
    function Initialize: Boolean; override;
    procedure Run; override;  
    function CreateAppCommandWindow: Boolean;
  end;
  
implementation
            
uses
  windef_msg,
  win.thread,
  BaseWinApp,
  //UtilsLog,
  UtilsParentProcess,
  //BaseStockApp,
  BaseStockFormApp,
  define_datasrc;

{$IFNDEF RELEASE}  
const
  LOGTAG = 'StockDealAgentApp.pas';
{$ENDIF}

var
  G_DealAgentApp: TDealAgentApp = nil;

function AppCommandWndProcA(AWnd: HWND; AMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  Result := 0;
  case AMsg of
    WM_AppStart: begin
      //Log(LOGTAG, 'WM_AppStart');
      if nil <> G_DealAgentApp then
      begin
      end else
      begin
      end;
    end;
    WM_AppRequestEnd: begin
      // query if should end      
      //Log(LOGTAG, 'WM_AppRequestEnd');
      if nil <> GlobalBaseStockApp then
      begin
        GlobalBaseStockApp.Terminate;
      end;
      PostMessage(AWnd, WM_AppNotifyEnd, 0, 0);
      //StartShutDownMonitorThread;   
    end;
    WM_AppNotifyEnd: begin
      if nil <> GlobalBaseStockApp then
      begin
        //GlobalBaseStockApp.Terminate;
      end;              
      //Log(LOGTAG, 'WM_AppNotifyEnd PostQuitMessage0');
      PostQuitMessage(0);
      //Log(LOGTAG, 'WM_AppNotifyEnd TerminateProcess');      
      //Windows.TerminateProcess(Windows.GetCurrentProcess, 0);
    end;
    WM_Console2Downloader_Command_Download_Day: begin
      //Log(LOGTAG, 'WM_Console2Downloader_Command_Download_Day:' + IntToStr(wParam) + '/' + IntToStr(lParam));
      PostMessage(AWnd, WM_Downloader_Command_Download_Day, wParam, lParam)
    end;
    WM_Console2Downloader_Command_Download_Detail: begin
      //Log(LOGTAG, 'WM_Console2Downloader_Command_Download_Day:' + IntToStr(wParam) + '/' + IntToStr(lParam));
      PostMessage(AWnd, WM_Downloader_Command_Download_Detail, wParam, lParam)
    end;
  end;
  Result := DefWindowProcA(AWnd, AMsg, wParam, lParam);
end;
               
constructor TDealAgentApp.Create(AHostApp: TBaseApp);
begin
  inherited;
  FillChar(fDealAgentAppData, SizeOf(fDealAgentAppData), 0);
  G_DealAgentApp := Self;
end;

destructor TDealAgentApp.Destroy;
begin
  if G_DealAgentApp = Self then
    G_DealAgentApp := nil;
  inherited;
end;
                  
function TDealAgentApp.Initialize: Boolean;
begin
  Result := inherited Initialize;
  if Result then
  begin                    
    Result := CreateAppCommandWindow;
  end;
  if Result then
  begin
    (*//
    UtilsLog.CloseLogFiles;
    UtilsLog.G_LogFile.FileName := ChangeFileExt(ParamStr(0), '.down.' + IntToStr(Windows.GetCurrentProcessId) + '.log');
    UtilsLog.SDLog(LOGTAG, 'init mode downloader');
    //*)
  end;
end;

procedure TDealAgentApp.Run;
begin
  PostMessage(TBaseWinApp(fBaseAppAgentData.HostApp).AppWindow, WM_AppStart, 0, 0);
  TBaseWinApp(fBaseAppAgentData.HostApp).RunAppMsgLoop;
end;

function TDealAgentApp.CreateAppCommandWindow: Boolean;
var
  tmpRegWinClass: TWndClassA;  
  tmpGetWinClass: TWndClassA;
  tmpIsReged: Boolean;
  tmpWindowName: AnsiString;
  tmpWndClassName: AnsiString;   
  tmpGuid: TGuid;
begin
  Result := false;          
  FillChar(tmpRegWinClass, SizeOf(tmpRegWinClass), 0);
  tmpRegWinClass.hInstance := HInstance;
  tmpRegWinClass.lpfnWndProc := @AppCommandWndProcA;
  //tmpWndClassName := AppCmdWndClassName_StockDataDownloader;
  
  CreateGuid(tmpGuid);
  tmpWndClassName := GuidToString(tmpGuid);
  
  tmpRegWinClass.lpszClassName := PAnsiChar(@tmpWndClassName[1]);
  tmpIsReged := GetClassInfoA(HInstance, tmpRegWinClass.lpszClassName, tmpGetWinClass);
  if tmpIsReged then
  begin
    if (tmpGetWinClass.lpfnWndProc <> tmpRegWinClass.lpfnWndProc) then
    begin                           
      UnregisterClassA(tmpRegWinClass.lpszClassName, HInstance);
      tmpIsReged := false;
    end;
  end;
  if not tmpIsReged then
  begin
    if 0 = RegisterClassA(tmpRegWinClass) then
      exit;
  end;
  tmpWindowName := IntToStr(GetCurrentProcessId);
  TBaseStockApp(fBaseAppAgentData.HostApp).AppWindow := CreateWindowExA(
    WS_EX_TOOLWINDOW
    //or WS_EX_APPWINDOW
    //or WS_EX_TOPMOST
    ,
    tmpRegWinClass.lpszClassName,
    PAnsiChar(tmpWindowName), WS_POPUP {+ 0},
    0, 0, 0, 0,
    HWND_MESSAGE, 0, HInstance, nil);
  Result := Windows.IsWindow(TBaseStockApp(fBaseAppAgentData.HostApp).AppWindow);
end;

end.
